package com.xbxkj.service.interceptor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xbxkj.service.config.redis.RedisHelper;
import com.xbxkj.service.util.MapDataUtil;
import com.xbxkj.util.Respons.ResponseUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.annotation.HttpConstraint;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Created by Zhang on 2018/8/26.
 */
@Configuration
public class ServertInterceptor implements HandlerInterceptor {
    @Autowired
    RedisHelper redisHelper;

    public final String TOKEN = "token";
    public final String REPEAT_PARAMS = "repeatParams";
    public final String REPEAT_TIME = "repeatTime";
    public final String URL = "url";
    @Value("${reloadTimeOut}")
    public   long TIME_OUT = 0;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //如果是post请求 对数据有操作的请求
        if (request.getMethod().equals("GET")) {
            //当前请求的URL
            String url = request.getRequestURI();
            //当前请求的用户令牌
            String token = request.getHeader("Authorization");
            //当前请求的参数
            String nowParams = JSON.toJSONString(request.getParameterMap());
            Map<String, Object> nowDataMap = new HashMap<String, Object>();
            nowDataMap.put(TOKEN, token);
            nowDataMap.put(URL, url);
            nowDataMap.put(REPEAT_PARAMS, nowParams);
            nowDataMap.put(REPEAT_TIME, System.currentTimeMillis());
            //如果是重复提交
             if(compareParams(nowDataMap)){
                 response.setContentType("application/json; charset=utf-8");
                 response.getWriter().print(JSONObject.toJSONString(ResponseUtil.getExceptionMapByReload()));
                 return  false;
             }
        }
        ;
        return true;
    }

    /**
     * 判断redis中是否存在该用户的 已提交请求  10S过期
     * true 是重复提交
     */
    private boolean compareParams(Map<String, Object> nowMap) {
        //获取本次用户的token
        String token = nowMap.get(TOKEN) + "";
        //获取本次用户的缓存请求map
        Object o = redisHelper.getValue(token);
        //如果是空的 说明 很久没访问了  缓存一下
        if (o == null) {
            pushRedis(token,nowMap);
            return false;
        }
        Map<String, Object> preMap = (Map<String, Object>) o;
        //用户当前请求的url
        String creeUrl = nowMap.get(URL) + "";
        //用户上次缓存的请求 url
        String preUrl = preMap.get(URL) + "";
        //如果路径相同 则证明已经是重复的提交  开始判断参数是否相同
        if (creeUrl.equals(preUrl)) {
            //如果参数相同
            if(compareParams(nowMap, preMap)){
                 return  true;
                 //如果参数不同 存入redis
            }else{
                pushRedis(token,nowMap);
                return  false;
            }
          //  否则 不是路径的重复的提交 存入redis  只存用户的一个请求路径
        } else {
            pushRedis(token,nowMap);
            return false;
        }

    }

    /**
     * 判断参数是否相同
     */
    private boolean compareParams(Map<String, Object> nowMap, Map<String, Object> preMap) {
        String nowParams = (String) nowMap.get(REPEAT_PARAMS);
        String preParams = (String) preMap.get(REPEAT_PARAMS);
        return nowParams.equals(preParams);
    }
    /**
     * 存入redis 新的请求
     */
    private boolean pushRedis(String token, Map<String, Object> nowMap) {
        //存入Redis
        redisHelper.valuePut(token, nowMap);
        //设置过期时间 10S 也就是 10S内不可以重复提交
        redisHelper.expirse(token, TIME_OUT, TimeUnit.MILLISECONDS);
        return  true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }


}
